package com.example.othree.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.othree.common.DataUtil;
import com.example.othree.common.PageParam;
import com.example.othree.common.R;
import com.example.othree.entity.*;
import com.example.othree.entity.PollutionHistoryDataJjjSites;
import com.example.othree.service.*;
import io.swagger.annotations.ApiOperation;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.geojson.feature.FeatureJSON;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.opengis.feature.simple.SimpleFeature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.dao.DataAccessException;
import org.springframework.web.bind.annotation.*;

import java.io.*;
import java.util.*;


/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zogran
 * @since 2024-11-12
 */
@RestController
@CrossOrigin
@RequestMapping("/api")
public class PollutionHistoryDataJjjSitesController {
    @Autowired
    private PollutionHistoryDataJjjSitesService pollutionHistoryDataJjjSitesService;

    @Autowired
    private PollutionHistoryDataJjjSitesDayService pollutionHistoryDataJjjSitesDayService;

    @Autowired
    private PollutionHistoryDataJjjSitesMonthService pollutionHistoryDataJjjSitesMonthService;

    @Autowired
    private PollutionHistoryDataJjjSitesSeasonService pollutionHistoryDataJjjSitesSeasonService;

    @Autowired
    private PollutionHistoryDataJjjSitesYearService pollutionHistoryDataJjjSitesYearService;

    @Autowired
    private JjjSitesInfoService jjjSitesInfoService;

    @Autowired
    private DataUtil dataUtil;

    @PostMapping("/sitesJjj/create")
    @ApiOperation("新增")
    public R create(@RequestBody PollutionHistoryDataJjjSites pollutionHistoryDataJjjSites) {
        return pollutionHistoryDataJjjSitesService.save(pollutionHistoryDataJjjSites) ? R.ok() : R.error();
    }

    @PostMapping("/sitesJjj/saveBatch")
    @ApiOperation("批量新增")
    public R saveBatch(@RequestBody List<PollutionHistoryDataJjjSites> pollutionHistoryDataJjjSitesList) {
        return pollutionHistoryDataJjjSitesService.saveBatch(pollutionHistoryDataJjjSitesList) ? R.ok() : R.error();
    }

    @GetMapping("/sitesJjj/list")
    public List<PollutionHistoryDataJjjSites> list() {
        return pollutionHistoryDataJjjSitesService.list();
    }

    @PostMapping("/sitesJjj/update")
    @ApiOperation("修改")
    public R update(@RequestBody PollutionHistoryDataJjjSites pollutionHistoryDataJjjSites) {
        return pollutionHistoryDataJjjSitesService.updateById(pollutionHistoryDataJjjSites) ? R.ok() : R.error();
    }

    @PostMapping("/sitesJjj/delete/{id}")
    public R delete(@PathVariable Integer id) {
        return pollutionHistoryDataJjjSitesService.removeById(id) ? R.ok() : R.error();
    }

    @PostMapping("/sitesJjj/listPage")
    @ApiOperation("查询、分页")
    public R listPage(@RequestBody PageParam pageParam) {
        HashMap param = pageParam.getParam();
        String hour = param.get("hour").toString();
        String station = param.get("station").toString();
        String date = param.get("date").toString();

        Page<PollutionHistoryDataJjjSites> page = new Page();
        page.setCurrent(pageParam.getPageNum());
        page.setSize(pageParam.getPageSize());

        LambdaQueryWrapper<PollutionHistoryDataJjjSites> lambdaQueryWrapper = new LambdaQueryWrapper();

        if (StringUtils.isNotBlank(hour) && !"null".equals(hour)) {
            lambdaQueryWrapper.eq(PollutionHistoryDataJjjSites::getHour, hour);
        }
        if (StringUtils.isNotBlank(station) && !"null".equals(station)) {
            lambdaQueryWrapper.eq(PollutionHistoryDataJjjSites::getStation, station);
        }
        if (StringUtils.isNotBlank(date) && !"null".equals(date)) {
            lambdaQueryWrapper.eq(PollutionHistoryDataJjjSites::getDate, date);
        }

        IPage result = pollutionHistoryDataJjjSitesService.PageList(page, lambdaQueryWrapper);

        return R.ok().data("result", result);
    }

    final float latLeft = 113.465369f;
    final float latRight = 119.872363f;
    final float lonTop = 42.618591f;
    final float lonBottem = 36.048205f;

    @GetMapping("/hebei-O3-analyze-data")
    @ApiOperation("获取河北省空气质量监测历史实况分析数据")
    public R pollutionAnalyzeData(@RequestParam("dataType") String dataType,
                                  @RequestParam("dataSubType") String dataSubType,
                                  @RequestParam("dataDecision") String dataDecision,
                                  @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {
        try {
            ArrayList<String[]> result = new ArrayList<>();
            ArrayList<Float[]> newResult = new ArrayList<>();

            HashMap<String, Float[]> siteForId = (jjjSitesInfoService.SitesInfoByCitys(new String[]{"邢台", "衡水", "北京", "天津", "石家庄", "唐山", "秦皇岛", "邯郸", "保定", "张家口", "承德", "廊坊", "沧州"}));
            if ("年平均".equals(dataType)) {
                List<PollutionHistoryDataJjjSitesYear> p = pollutionHistoryDataJjjSitesYearService.pollutionAnalyzeDataByDate(startTime, endTime, new String[]{"邢台", "衡水", "北京", "天津", "石家庄", "唐山", "秦皇岛", "邯郸", "保定", "张家口", "承德", "廊坊", "沧州"});

                for (PollutionHistoryDataJjjSitesYear i : p) {
                    Float[] lonLat = siteForId.get(i.getStation());
                    if (i.getO3() == null){
                        i.setO3(0);
                    }
                    String[] analyzeData = new String[]{
                            i.getYear(),
                            lonLat[0].toString(),
                            lonLat[1].toString(),
//                            i.getAqi().toString(),
//                            i.getO3().toString(),
//                            i.getPm25().toString(),
//                            i.getPm10().toString(),
//                            i.getSo2().toString(),
//                            i.getNo2().toString(),
//                            i.getCo().toString()
                            (i.getAqi() == null ? null : i.getAqi().toString()),
                            (i.getO3() == null ? null : i.getO3().toString()),
                            (i.getPm25() == null ? null : i.getPm25().toString()),
                            (i.getPm10() == null ? null : i.getPm10().toString()),
                            (i.getSo2() == null ? null : i.getSo2().toString()),
                            (i.getNo2() == null ? null : i.getNo2().toString()),
                            (i.getCo() == null ? null : i.getCo().toString())
                    };
                    result.add(analyzeData);
                }
            } else if ("季平均".equals(dataType)) {
                if (dataSubType.isEmpty()) dataSubType = "春";
                List<PollutionHistoryDataJjjSitesSeason> p = pollutionHistoryDataJjjSitesSeasonService.pollutionAnalyzeDataByDate(startTime, endTime, dataSubType, new String[]{"邢台", "衡水", "北京", "天津", "石家庄", "唐山", "秦皇岛", "邯郸", "保定", "张家口", "承德", "廊坊", "沧州"});

                for (PollutionHistoryDataJjjSitesSeason i : p) {
                    Float[] lonLat = siteForId.get(i.getStation());
                    if (i.getO3() == null){
                        i.setO3(0);
                    }
                    String[] analyzeData = new String[]{
                            i.getYear(),
                            lonLat[0].toString(),
                            lonLat[1].toString(),
                            (i.getAqi() == null ? null : i.getAqi().toString()),
                            (i.getO3() == null ? null : i.getO3().toString()),
                            (i.getPm25() == null ? null : i.getPm25().toString()),
                            (i.getPm10() == null ? null : i.getPm10().toString()),
                            (i.getSo2() == null ? null : i.getSo2().toString()),
                            (i.getNo2() == null ? null : i.getNo2().toString()),
                            (i.getCo() == null ? null : i.getCo().toString())
                    };
                    result.add(analyzeData);
                }


            } else if ("月平均".equals(dataType)) {
                if (dataSubType.isEmpty()) dataSubType = "1月";
                List<PollutionHistoryDataJjjSitesMonth> p = pollutionHistoryDataJjjSitesMonthService.pollutionAnalyzeDataByDate(startTime, endTime, dataSubType, new String[]{"邢台", "衡水", "北京", "天津", "石家庄", "唐山", "秦皇岛", "邯郸", "保定", "张家口", "承德", "廊坊", "沧州"});

                for (PollutionHistoryDataJjjSitesMonth i : p) {
                    Float[] lonLat = siteForId.get(i.getStation());
                    if (i.getO3() == null){
                        i.setO3(0);
                    }
                    String[] analyzeData = new String[]{
                            i.getMonth(),
                            lonLat[0].toString(),
                            lonLat[1].toString(),
                            (i.getAqi() == null ? null : i.getAqi().toString()),
                            (i.getO3() == null ? null : i.getO3().toString()),
                            (i.getPm25() == null ? null : i.getPm25().toString()),
                            (i.getPm10() == null ? null : i.getPm10().toString()),
                            (i.getSo2() == null ? null : i.getSo2().toString()),
                            (i.getNo2() == null ? null : i.getNo2().toString()),
                            (i.getCo() == null ? null : i.getCo().toString())
                    };
                    result.add(analyzeData);
                }
            }


            if ("站点".equals(dataDecision)) {
                return R.ok().data("data", result);
            } else if ("格点".equals(dataDecision)) {
                float[][] grid = dataUtil.gridLonLat(latLeft, latRight, lonTop, lonBottem, 200);
                ArrayList<Float[]> value = StrToFloat(result, 1);
                ArrayList<Float[]> gridData = new ArrayList<Float[]>();


                GeometryFactory geometryFactory = new GeometryFactory();
                // 将 float[][] 转换为 Geometry
                Coordinate[] coordinates = new Coordinate[grid[0].length];
                for (int i = 0; i < grid[0].length; i++) {
                    coordinates[i] = new Coordinate(grid[0][i], grid[1][i]);
                }
                Geometry geometry = geometryFactory.createLineString(coordinates);

                float[][] points = isPointInHebei(geometry);
                for (int i = 0; i < points.length; i++) {
                    gridData.add(dataUtil.idwInterpolation(value, points[i][0], points[i][1], 2.0f));
                }
                newResult = gridData;
            }


            return R.ok().data("data", newResult);

        } catch (DataAccessException e) {
            e.printStackTrace();
            return R.error().message("数据库访问出错");
        } catch (Exception e) {
            e.printStackTrace();
            return R.error().message("出现了未知错误");
        }

    }


    @GetMapping("/region-O3-data")
    @ApiOperation("获取邢台和衡水市空气质量监测历史实况分析数据")
    public R pollutionAnalyzeDataForCity(@RequestParam("dataType") String dataType,
                                         @RequestParam("dataSubType") String dataSubType,
                                         @RequestParam("element") String element,
                                         @RequestParam("region") String region,
                                         @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {
        HashMap<String, Object> result = new HashMap<>();

        try {

            if ("O31H".equals(element.toUpperCase(Locale.ROOT))) element = "O3";
            else if ("O38H".equals(element.toUpperCase(Locale.ROOT))) element = "O3_8h";

            if ("平均数据".equals(dataType)) {
                if ("月平均".equals(dataSubType)) {
                    ArrayList<Float> dataAveg = pollutionHistoryDataJjjSitesMonthService.pollutionAnalyzeDataByCityForAvg(startTime, endTime, element, new String[]{region});
                    for (int i = 1; i < 13; i++) {
                        result.put(i + "月", dataAveg.get(i - 1));
                    }
                } else if ("季平均".equals(dataSubType)) {
                    List<HashMap<String, String>> dataAveg = pollutionHistoryDataJjjSitesSeasonService.pollutionAnalyzeDataByCityForAvg(startTime, endTime, element, new String[]{region});
                    for (HashMap<String, String> i : dataAveg) {
                        result.put(i.get("season"), i.get("data"));
                    }
                } else if ("年平均".equals(dataSubType)) {
                    List<HashMap<String, String>> dataAveg = pollutionHistoryDataJjjSitesYearService.pollutionAnalyzeDataByCityForAvg(startTime, endTime, element, new String[]{region});
                    for (HashMap<String, String> i : dataAveg) {
                        result.put(i.get("year"), i.get("data"));
                    }
                } else if ("日平均".equals(dataSubType)) {
                    List<HashMap<String, String>> dataAveg = pollutionHistoryDataJjjSitesDayService.pollutionAnalyzeDataByCityForAvg(startTime, endTime, element, new String[]{region});
                    for (HashMap<String, String> i : dataAveg) {
                        result.put(i.get("date"), i.get("data"));
                    }
                }
            } else if ("实况数据".equals(dataType)) {
                if ("逐月".equals(dataSubType)) {
                    List<HashMap<String, String>> dataEvery = pollutionHistoryDataJjjSitesMonthService.pollutionAnalyzeDataByCityForEvery(startTime, endTime, element, new String[]{region});
                    for (HashMap<String, String> i : dataEvery) {
                        result.put(i.get("month"), i.get("data"));
                    }
                } else if ("逐日".equals(dataSubType)) {
                    List<HashMap<String, String>> dataEvery = pollutionHistoryDataJjjSitesDayService.pollutionAnalyzeDataByCityForEvery(startTime, endTime, element, new String[]{region});
                    for (HashMap<String, String> i : dataEvery) {
                        result.put(i.get("date"), i.get("data"));
                    }
                }else if ("逐时".equals(dataSubType)) {
                    if ("PM2.5".equals(element.toUpperCase(Locale.ROOT))) element = "PM25";
                    List<HashMap<String, String>> dataEvery = pollutionHistoryDataJjjSitesService.pollutionAnalyzeDataByCityForEvery(startTime, endTime, element, new String[]{region});
                    for (HashMap<String, String> i : dataEvery) {
                        result.put(i.get("date"), i.get("data"));
                    }
                }

            }
        } catch (DataAccessException e) {
            e.printStackTrace();
            return R.error().message("数据库访问出错");
        } catch (Exception e) {
            e.printStackTrace();
            return R.error().message("出现了未知错误");
        }

        return R.ok().data("data", result);
    }

    @GetMapping("/O3-data-detail")
    @ApiOperation("获取空气质量监测实况数据详情")
    public R pollutionAnalyzeDataForCity(@RequestParam("dataType") String dataType,
                                         @RequestParam("element") String element,
                                         @RequestParam("region") String region,
                                         @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime,
                                         @RequestParam(value = "page", defaultValue = "1") int page,
                                         @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
        HashMap<String, Object> resultPage = new HashMap<>();
        ArrayList<HashMap<String, String>> result = null;
        try {
            String[] cities = null;
            if ("河北省".equals(region)) cities = new String[]{"邢台", "衡水", "北京", "天津", "石家庄", "唐山", "秦皇岛", "邯郸", "保定", "张家口", "承德", "廊坊", "沧州"};
            else cities = new String[]{region};

            String[] elements = element.split(",");

            for (int i = 0; i < elements.length;i++){
                if ("O31H".equals(elements[i].toUpperCase(Locale.ROOT))) elements[i] = "O3";
                else if ("O38H".equals(elements[i].toUpperCase(Locale.ROOT))) elements[i] = "O3_8H";
                else if ("PM2.5".equals(elements[i].toUpperCase(Locale.ROOT))) {
                    if ("逐时".equals(dataType)) elements[i] = "PM25";
                }
            }

            IPage<HashMap<String, String>> pageData = new Page();
            pageData.setSize(pageSize);
            pageData.setCurrent(page);


            if ("逐日".equals(dataType)) {
                pollutionHistoryDataJjjSitesDayService.pollutionPageList(pageData, cities, elements, startTime, endTime);
            } else if ("逐时".equals(dataType)) {
                pollutionHistoryDataJjjSitesService.pollutionPageList(pageData, cities, elements, startTime, endTime);
            }

            result = new ArrayList<>(pageData.getRecords());
            for (HashMap<String, String> i : result){
                if (i.get("pm25").isEmpty()){

                }else {
                    String data = i.get("pm25");
                    i.remove("pm25");
                    i.put("pm2.5", data);
                }
            }
            resultPage.put("data", result);

            resultPage.put("total", pageData.getTotal());
            resultPage.put("currentPage", pageData.getCurrent());
            resultPage.put("pageSize", pageData.getSize());
            resultPage.put("totalPages", pageData.getPages());

        } catch (DataAccessException e) {
            e.printStackTrace();
            return R.error().message("数据库访问出错");
        } catch (Exception e) {
            e.printStackTrace();
            return R.error().message("出现了未知错误");
        }


        return R.ok().data("data", resultPage);
    }


    @GetMapping("/hebei-O3-real-data")
    @ApiOperation("获取河北省空气质量监测实况逐时数据")
    public R pollutionDataAllByDate(@RequestParam("dataDecision") String dataDecision,
                                    @RequestParam("element") String element,
                                    @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {

        HashMap<String, HashMap<String, Object>> newResult = new HashMap<>();
        HashMap<String, HashMap<String, HashMap<String, HashMap<String, Object>>>> result = new HashMap<>();

        try {
            HashMap<String, Float[]> siteForId = (jjjSitesInfoService.SitesInfoAll());
            List<PollutionHistoryDataJjjSites> p = pollutionHistoryDataJjjSitesService.pollutionDataForHour(new String[]{"邢台", "衡水", "石家庄"}, element, startTime, endTime);

            for (PollutionHistoryDataJjjSites i : p) {
                Float[] lonLat = siteForId.get(i.getStation());
                HashMap<String, Object> dataMap = new HashMap<>();
                dataMap.put("date", i.getDate());
                dataMap.put("hour", i.getHour());
                dataMap.put("station", i.getStation());
                dataMap.put("Lon", lonLat[0]);
                dataMap.put("Lat", lonLat[1]);
                if ("O31h".equals(element)){
                    dataMap.put(element, i.getO3());
                }else if ("O38h".equals(element)){
                    dataMap.put(element, i.getO38h());
                }else if ("PM2.5".equals(element)){
                    dataMap.put(element, i.getPm25());
                }else if ("PM10".equals(element)){
                    dataMap.put(element, i.getPm10());
                }else if ("SO2".equals(element)){
                    dataMap.put(element, i.getSo2());
                }else if ("NO2".equals(element)){
                    dataMap.put(element, i.getNo2());
                }else if ("CO".equals(element)){
                    dataMap.put(element, i.getCo());
                }else if ("AQI".equals(element)){
                    dataMap.put(element, i.getAqi());
                }

                if (result.get(i.getDate()) == null) {
                    result.put(i.getDate(), new HashMap<String, HashMap<String, HashMap<String, Object>>>());
                }
                if (result.get(i.getDate()).get(i.getHour().toString()) == null) {
                    result.get(i.getDate()).put(i.getHour().toString(), new HashMap<String, HashMap<String, Object>>());
                }
                result.get(i.getDate()).get(i.getHour().toString()).put(i.getStation(), dataMap);
            }


            if ("站点".equals(dataDecision)) {
                return R.ok().data("data", result);
            } else if ("格点".equals(dataDecision)) {

                float[][] grid = dataUtil.gridLonLat(latLeft, latRight, lonTop, lonBottem, 200);

                for (String key : result.keySet()) {
                    for (String keyI : result.get(key).keySet()) {

                        ArrayList<Float[]> value = new ArrayList<>();
                        for (String keyJ : result.get(key).get(keyI).keySet()) {

                            Float dataLon = null;
                            Float dataLat = null;
                            Float dataElement = null;
                            Object dataStrElement = ((HashMap<String, Object>) result.get(key).get(keyI).get(keyJ)).get(element);
                            if (dataStrElement instanceof Integer) {
                                dataElement = ((Integer) dataStrElement).floatValue();
                            } else if (dataStrElement instanceof Float) {
                                dataElement = ((Float) dataStrElement).floatValue();
                            } else if (dataStrElement == null){
                                dataElement = 0f;
                            }
                            Object dataStrLon = ((HashMap<String, Object>) result.get(key).get(keyI).get(keyJ)).get("Lon");
                            if (dataStrLon instanceof Float) {
                                dataLon = ((Float) dataStrLon).floatValue();
                            } else if (dataStrLon == null){
                                dataLon = 0f;
                            }
                            Object dataStrLat = ((HashMap<String, Object>) result.get(key).get(keyI).get(keyJ)).get("Lat");
                            if (dataStrLat instanceof Float) {
                                dataLat = ((Float) dataStrLat).floatValue();
                            } else if (dataStrLat == null){
                                dataLat = 0f;
                            }
                            value.add(new Float[]{dataLon, dataLat, dataElement});
                        }
                        ArrayList<Float[]> gridData = new ArrayList<Float[]>();

                        for (int i = 0; i < 200 * 200; i++) {

                            boolean isInHebei = isPointInHebei(grid[0][i], grid[1][i]);
                            if (isInHebei) {
                                gridData.add(dataUtil.idwInterpolation(value, grid[0][i], grid[1][i], 2.0f));
                            } else {

                            }
                        }
                        if (newResult.get(key) == null) {
                            newResult.put(key, new HashMap<String, Object>());
                        }
                        newResult.get(key).put(keyI, gridData);


                    }
                }
            }

        } catch (DataAccessException e) {
            e.printStackTrace();
            return R.error().message("数据库访问出错");
        } catch (Exception e) {
            e.printStackTrace();
            return R.error().message("出现了未知错误");
        }
        return R.ok().data("data", newResult);
    }
    @GetMapping("/region-O3-data-statistics")
    @ApiOperation("获取邢台或衡水某个时间范围内各空气质量等级（优、良、轻度污染、中度污染、重度污染、严重污染）分布占比。")
    public R pollutionDataLevelAllByDate(@RequestParam("dataSubType") String dataSubType,
                                    @RequestParam("dataType") String dataType,
                                    @RequestParam("region") String region,
                                    @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime){
        HashMap<String, Object> result = new HashMap<>();
        try{
            if ("月份".equals(dataType)){
                PollutionHistoryDataJjjSitesMonth p = pollutionHistoryDataJjjSitesMonthService.pollutionForLevel(startTime, endTime, region, dataSubType);
                if (p != null){
                    result.put("优", p.getLevel1Count().toString()
                            + ":"
                            + String.format("%.2f%%", (p.getLevel1Count() * 100f /p.getMonthTotalCount())));
                    result.put("良", p.getLevel2Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel2Count() * 100f /p.getMonthTotalCount()));
                    result.put("轻度污染", p.getLevel3Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel3Count() * 100f /p.getMonthTotalCount()));
                    result.put("中度污染", p.getLevel4Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel4Count() * 100f /p.getMonthTotalCount()));
                    result.put("重度污染", p.getLevel5Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel5Count() * 100f /p.getMonthTotalCount()));
                    result.put("严重污染", p.getLevel6Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel6Count() * 100f /p.getMonthTotalCount()));
                }

            }else if ("季节".equals(dataType)){

                PollutionHistoryDataJjjSitesSeason p = pollutionHistoryDataJjjSitesSeasonService.pollutionForLevel(startTime, endTime, region, dataSubType);
                if (p != null){
                    result.put("优", p.getLevel1Count().toString()
                            + ":"
                            + String.format("%.2f%%", (p.getLevel1Count() * 100f /Float.valueOf(p.getSeasonTotalCount()))));
                    result.put("良", p.getLevel2Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel2Count() * 100f /Float.valueOf(p.getSeasonTotalCount())));
                    result.put("轻度污染", p.getLevel3Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel3Count() * 100f /Float.valueOf(p.getSeasonTotalCount())));
                    result.put("中度污染", p.getLevel4Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel4Count() * 100f /Float.valueOf(p.getSeasonTotalCount())));
                    result.put("重度污染", p.getLevel5Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel5Count() * 100f /Float.valueOf(p.getSeasonTotalCount())));
                    result.put("严重污染", p.getLevel6Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel6Count() * 100f /Float.valueOf(p.getSeasonTotalCount())));
                }
            }else if ("年份".equals(dataType)){
                PollutionHistoryDataJjjSitesYear p = pollutionHistoryDataJjjSitesYearService.pollutionForLevel(startTime, endTime, region);
                if (p != null){
                    result.put("优", p.getLevel1Count().toString()
                            + ":"
                            + String.format("%.2f%%", (p.getLevel1Count() * 100f /Float.valueOf(p.getYearTotalCount()))));
                    result.put("良", p.getLevel2Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel2Count() * 100f /Float.valueOf(p.getYearTotalCount())));
                    result.put("轻度污染", p.getLevel3Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel3Count() * 100f /Float.valueOf(p.getYearTotalCount())));
                    result.put("中度污染", p.getLevel4Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel4Count() * 100f /Float.valueOf(p.getYearTotalCount())));
                    result.put("重度污染", p.getLevel5Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel5Count() * 100f /Float.valueOf(p.getYearTotalCount())));
                    result.put("严重污染", p.getLevel6Count().toString()
                            + ":"
                            + String.format("%.2f%%", p.getLevel6Count() * 100f /Float.valueOf(p.getYearTotalCount())));
                }
            }

        } catch (DataAccessException e) {
            e.printStackTrace();
            return R.error().message("数据库访问出错");
        } catch (Exception e) {
            e.printStackTrace();
            return R.error().message("出现了未知错误");
        }
        return R.ok().data("data", result);
    }

    @GetMapping("/region-primariy-statistics")
    @ApiOperation("获取邢台和衡水市空气质量监测历史实况之首要污染物统计分布数据")
    public R pollutionDataCountAllByDate(@RequestParam("dataSubType") String dataSubType,
                                    @RequestParam("dataType") String dataType,
                                    @RequestParam("region") String region,
                                    @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime){
        HashMap<String, Object> result = new HashMap<>();
        try{
            if ("月份".equals(dataType)){
                PollutionHistoryDataJjjSitesMonth p = pollutionHistoryDataJjjSitesMonthService.pollutionForCount(startTime, endTime, region, dataSubType);

                Float sum = p.getCoCount() + p.getNo2Count() + p.getSo2Count() + p.getPm10Count() + p.getPm25Count()
                        + p.getO3Count() + 0f + p.getO38hCount();

                int start_year = Integer.valueOf(startTime);
                int end_year = Integer.valueOf(endTime);
                Float number_of_years = end_year - start_year + 1.0f;



                result.put("CO", (p.getCoCount() / number_of_years)
                        + ":"
                        + String.format("%.2f%%", (p.getCoCount() * 100f /sum)));
                result.put("NO2", p.getNo2Count().toString()
                        + ":"
                        + String.format("%.2f%%", p.getNo2Count() * 100f /sum));
                result.put("SO2", p.getSo2Count() / number_of_years
                        + ":"
                        + String.format("%.2f%%", p.getSo2Count() * 100f /sum));
                result.put("Pm10", p.getPm10Count() / number_of_years
                        + ":"
                        + String.format("%.2f%%", p.getPm10Count() * 100f /sum));
                result.put("PM2.5", p.getPm25Count() / number_of_years
                        + ":"
                        + String.format("%.2f%%", p.getPm25Count() * 100f /sum));
                result.put("O3", (p.getO3Count() + p.getO38hCount()) / number_of_years
                        + ":"
                        + String.format("%.2f%%", (p.getO3Count() + p.getO38hCount()) * 100f / sum));
              }else if ("季节".equals(dataType)){
                PollutionHistoryDataJjjSitesSeason p = pollutionHistoryDataJjjSitesSeasonService.pollutionForCount(startTime, endTime, region, dataSubType);

                Float sum = p.getCoCount() + p.getNo2Count() + p.getSo2Count() + p.getPm10Count() + p.getPm25Count()
                        + p.getO3Count() + 0f + p.getO38hCount();
                int start_year = Integer.valueOf(startTime);
                int end_year = Integer.valueOf(endTime);
                Float number_of_years = end_year - start_year + 1.0f;

                result.put("CO", p.getCoCount() / number_of_years
                        + ":"
                        + String.format("%.2f%%", (p.getCoCount() * 100f / sum)));
                result.put("NO2", p.getNo2Count() / number_of_years
                        + ":"
                        + String.format("%.2f%%", p.getNo2Count() * 100f / sum));
                result.put("SO2", p.getSo2Count() / number_of_years
                        + ":"
                        + String.format("%.2f%%", p.getSo2Count() * 100f / sum));
                result.put("Pm10", p.getPm10Count() / number_of_years
                        + ":"
                        + String.format("%.2f%%", p.getPm10Count() * 100f / sum));
                result.put("PM2.5", p.getPm25Count() / number_of_years
                        + ":"
                        + String.format("%.2f%%", p.getPm25Count() * 100f / sum));
                result.put("O3", (p.getO3Count() + p.getO38hCount()) / number_of_years
                        + ":"
                        + String.format("%.2f%%", (p.getO3Count() + p.getO38hCount()) * 100f / sum));
               }else if ("年份".equals(dataType)){
                PollutionHistoryDataJjjSitesYear p = pollutionHistoryDataJjjSitesYearService.pollutionForCount(startTime, endTime, region);

                Float sum = p.getCoCount() + p.getNo2Count() + p.getSo2Count() + p.getPm10Count() + p.getPm25Count()
                        + p.getO3Count() + 0f + p.getO38hCount();
                int start_year = Integer.valueOf(startTime);
                int end_year = Integer.valueOf(endTime);
                Float number_of_years = end_year - start_year + 1.0f;

                result.put("CO", p.getCoCount() / number_of_years
                        + ":"
                        + String.format("%.2f%%", (p.getCoCount() * 100f / sum)));
                result.put("NO2", p.getNo2Count() / number_of_years
                        + ":"
                        + String.format("%.2f%%", p.getNo2Count() * 100f / sum));
                result.put("SO2", p.getSo2Count() / number_of_years
                        + ":"
                        + String.format("%.2f%%", p.getSo2Count() * 100f / sum));
                result.put("Pm10", p.getPm10Count() / number_of_years
                        + ":"
                        + String.format("%.2f%%", p.getPm10Count() * 100f / sum));
                result.put("PM2.5", p.getPm25Count() / number_of_years
                        + ":"
                        + String.format("%.2f%%", p.getPm25Count() * 100f / sum));
                result.put("O3", (p.getO3Count() + p.getO38hCount()) / number_of_years
                        + ":"
                        + String.format("%.2f%%", (p.getO3Count() + p.getO38hCount()) * 100f / sum));
            }

        } catch (DataAccessException e) {
            e.printStackTrace();
            return R.error().message("数据库访问出错");
        } catch (Exception e) {
            e.printStackTrace();
            return R.error().message("出现了未知错误");
        }
        return R.ok().data("data", result);
    }



    public ArrayList<Float[]> StrToFloat(ArrayList<String[]> strList, int num) {

        // 转换后的ArrayList<Float[]>
        ArrayList<Float[]> convertedList = new ArrayList<>();

        // 遍历原始列表
        for (String[] strings : strList) {
            // 创建一个新的Float数组，长度为原始String数组长度减1
            Float[] floats = new Float[strings.length - num];

            // 将String数组（除了第一列）转换为Float数组
            for (int i = num; i < strings.length; i++) {
                floats[i - num] = Float.parseFloat(strings[i]);
            }

            // 将新的Float数组添加到转换后的列表中
            convertedList.add(floats);
        }

        return convertedList;
    }

    @Value("${data.geo.1}")
    String fileGeoOne;

    @Value("${data.geo.2}")
    String fileGeoTwo;
    @Value("${data.geo.3}")
    String fileGeoThree;

    private static Geometry hebeiBoundaryOne = null;
    private static Geometry hebeiBoundaryTwo = null;
    private static Geometry hebeiBoundaryThree = null;

    private boolean isPointInHebei(double lon, double lat) throws Exception {
        // 读取河北省的边界数据
        if (hebeiBoundaryOne == null){

            ClassPathResource resource = new ClassPathResource(fileGeoOne);
            hebeiBoundaryOne = readHebeiBoundary(resource.getInputStream());
        }
        if (hebeiBoundaryTwo == null){
            ClassPathResource resource = new ClassPathResource(fileGeoTwo);
            hebeiBoundaryTwo = readHebeiBoundary(resource.getInputStream());
        }
        if (hebeiBoundaryThree == null){
            ClassPathResource resource = new ClassPathResource(fileGeoThree);
            hebeiBoundaryThree = readHebeiBoundary(resource.getInputStream());
        }

        // 创建点
        GeometryFactory geometryFactory = new GeometryFactory();
        Point point = geometryFactory.createPoint(new Coordinate(lon, lat));


        if (!hebeiBoundaryThree.isValid()) {
            hebeiBoundaryThree = hebeiBoundaryThree.buffer(0);
        }
        boolean qw = hebeiBoundaryThree.isValid();
        boolean we = hebeiBoundaryOne.isValid();

        // 判断点是否在多边形内
        return (hebeiBoundaryOne.contains(point) || hebeiBoundaryTwo.contains(point) || hebeiBoundaryThree.contains(point));
    }

    public float[][] isPointInHebei(Geometry G){
        if (hebeiBoundaryOne == null){

            ClassPathResource resource = new ClassPathResource(fileGeoOne);
            try {
                hebeiBoundaryOne = readHebeiBoundary(resource.getInputStream());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (hebeiBoundaryTwo == null){
            ClassPathResource resource = new ClassPathResource(fileGeoTwo);
            try {
                hebeiBoundaryTwo = readHebeiBoundary(resource.getInputStream());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (hebeiBoundaryThree == null){
            ClassPathResource resource = new ClassPathResource(fileGeoThree);
            try {
                hebeiBoundaryThree = readHebeiBoundary(resource.getInputStream());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (!hebeiBoundaryOne.isValid()) {
            throw new IllegalArgumentException("Geometry is not valid: " + hebeiBoundaryOne.getGeometryType());
        }
        if (!hebeiBoundaryTwo.isValid()) {
            throw new IllegalArgumentException("Geometry is not valid: " + hebeiBoundaryTwo.getGeometryType());
        }
        if (!hebeiBoundaryThree.isValid()) {
            hebeiBoundaryThree = hebeiBoundaryThree.buffer(0);
        }
        if (!hebeiBoundaryThree.isValid()) {
            throw new IllegalArgumentException("Geometry is not valid: " + hebeiBoundaryThree.getGeometryType());
        }
        Geometry geometry = hebeiBoundaryOne.union(hebeiBoundaryTwo.union(hebeiBoundaryThree));

        Coordinate[] coordinates = G.intersection(geometry).getCoordinates();
        float[][] result = new float[coordinates.length][2];

        // 遍历 Coordinate[]，将 x 和 y 值提取到 float[][]
        for (int i = 0; i < coordinates.length; i++) {
            result[i][0] = (float) coordinates[i].x;  // X 坐标
            result[i][1] = (float) coordinates[i].y;  // Y 坐标
        }

        return result;
    }

    private Geometry readHebeiBoundary(InputStream inputStream) throws Exception {
        // 读取GeoJSON文件
//        FileReader reader = new FileReader(fileURL);
        Reader reader = new InputStreamReader(inputStream);

        FeatureJSON featureJSON = new FeatureJSON();

        SimpleFeatureCollection featureCollection = (SimpleFeatureCollection) featureJSON.readFeatureCollection(reader);

        try (SimpleFeatureIterator featureIterator = featureCollection.features()) {
            if (featureIterator.hasNext()) {
                SimpleFeature feature = featureIterator.next();
                return (Geometry) feature.getDefaultGeometry();
            }
        }
        return null;
    }
}

